<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h3 data-lake-id="gl73M" id="gl73M"><span data-lake-id="uc53562d7" id="uc53562d7">问题发现</span></h3>
  <p data-lake-id="u01cefbd6" id="u01cefbd6"><br></p>
  <p data-lake-id="uf6e1db6c" id="uf6e1db6c"><span data-lake-id="ueade470d" id="ueade470d">通过监控工平台，查看到定价集群存在少量FullGC的情况，FullGC对于程序员来说其实是不能忍的，于是开始排查。</span></p>
  <p data-lake-id="u9fa98c1f" id="u9fa98c1f"><span data-lake-id="ucafd5224" id="ucafd5224">​</span><br></p>
  <p data-lake-id="u20ee9c0b" id="u20ee9c0b"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680089336683-0c6e8b61-4e89-4128-ad99-b100f3769bee.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_38%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ud7def1ef" id="ud7def1ef"><br></p>
  <p data-lake-id="ub502216d" id="ub502216d"><span data-lake-id="u52c58e01" id="u52c58e01">监控提示是MetaSpace发生fullGC，Metaspace中的类需要满足什么条件才能够被当成垃圾被卸载回收？</span></p>
  <p data-lake-id="u73fbbc3e" id="u73fbbc3e"><span data-lake-id="u8c8932e5" id="u8c8932e5">条件还是比较严苛的，需同时满足如下三个条件的类才会被卸载：</span></p>
  <ol list="u78f08743">
   <li fid="uf03e3303" data-lake-id="uf92cfcea" id="uf92cfcea"><span data-lake-id="ud4f32e98" id="ud4f32e98">该类所有的实例都已经被回收；</span></li>
   <li fid="uf03e3303" data-lake-id="u4d4a663d" id="u4d4a663d"><span data-lake-id="uad7d27f2" id="uad7d27f2">加载该类的ClassLoader已经被回收；</span></li>
   <li fid="uf03e3303" data-lake-id="uf322d1ce" id="uf322d1ce"><span data-lake-id="uc24f158a" id="uc24f158a">该类对应的java.lang.Class对象没有任何地方被引用。</span></li>
  </ol>
  <p data-lake-id="u7778d9c7" id="u7778d9c7"><br></p>
  <h3 data-lake-id="ubwnh" id="ubwnh"><span data-lake-id="u3272e2be" id="u3272e2be">问题定位</span></h3>
  <p data-lake-id="u44a658ef" id="u44a658ef"><br></p>
  <p data-lake-id="ufd393f13" id="ufd393f13"><span data-lake-id="u7abb0992" id="u7abb0992">初步推测是有不停的动态创建类的过程，且有类未被回收；后来考虑到定价中存在轻量的表达式引擎AviatorEvaluator，会存在此过程；</span></p>
  <p data-lake-id="u72686363" id="u72686363"><span data-lake-id="ue2211bdb" id="ue2211bdb">​</span><br></p>
  <p data-lake-id="ubec92964" id="ubec92964"><span data-lake-id="u09ee1627" id="u09ee1627">于是dump出metaspace和heap</span></p>
  <p data-lake-id="uc4c3d406" id="uc4c3d406"><span data-lake-id="u16eb338c" id="u16eb338c">​</span><br></p>
  <p data-lake-id="u8ff8a944" id="u8ff8a944"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680089460712-a6c4ba9a-34c5-485f-a6ed-c2605fbd6c76.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_42%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ubba65aa1" id="ubba65aa1"><br></p>
  <p data-lake-id="u870a56cb" id="u870a56cb"><br></p>
  <p data-lake-id="u1383e3c7" id="u1383e3c7"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680089495465-20cc538c-ad0a-421a-8c42-363925fe4098.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_51%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="uee87c690" id="uee87c690"><br></p>
  <p data-lake-id="ua2f508c9" id="ua2f508c9"><span data-lake-id="u0571fd8b" id="u0571fd8b">可以看到，存在非常多的Scrip_${timestamp}_${idx}类型的类</span></p>
  <p data-lake-id="u77c0ba67" id="u77c0ba67"><span data-lake-id="u0ba1b3db" id="u0ba1b3db">​</span><br></p>
  <p data-lake-id="u38668f14" id="u38668f14"><span data-lake-id="uf05d086a" id="uf05d086a">重复加载的类中，Top都是关于lambda表达式的</span></p>
  <p data-lake-id="ub4bd8850" id="ub4bd8850"><span data-lake-id="uea5d368b" id="uea5d368b">​</span><br></p>
  <p data-lake-id="uf8cb1f3f" id="uf8cb1f3f"><span data-lake-id="u24bcc2ac" id="u24bcc2ac">且指向了com.googlecode.aviator包 - 表达式引擎</span></p>
  <p data-lake-id="ucd8ced83" id="ucd8ced83"><span data-lake-id="u3c98ebe0" id="u3c98ebe0">​</span><br></p>
  <p data-lake-id="u571147b4" id="u571147b4"><span data-lake-id="uaa9cc95d" id="uaa9cc95d">找到了我的代码：</span></p>
  <p data-lake-id="u603d5aec" id="u603d5aec"><span data-lake-id="uc4e378e8" id="uc4e378e8">​</span><br></p>
  <pre lang="java"><code>
/**
 * 表达式处理工具类
 *
 * @author Hollis
 */
public class ExpressionUtil {

    public static AviatorEvaluatorInstance aviatorEvaluator = AviatorEvaluator.getInstance();

    static {
        aviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
        aviatorEvaluator.setOption(Options.ALWAYS_PARSE_INTEGRAL_NUMBER_INTO_DECIMAL, true);
    }

    public static boolean verify(String expression, Map&lt;String, Object&gt; params) {
        return (Boolean)aviatorEvaluator.compile(expression).execute(params);
    }

    /**
     * 表达式计算
     * @param expression 表达式
     * @param params 需要替换的表达式参数
     * @return calculate result
     */
    public static BigDecimal calculate(String expression, Map&lt;String, Object&gt; params) {
        BigDecimal result = (BigDecimal)aviatorEvaluator.compile(expression).execute(params);
        return result.setScale(6, RoundingMode.HALF_UP);
    }
}

/**
   * Compile a text expression to Expression Object without caching
   *
   * @param expression
   * @return
   */
public Expression compile(final String expression) {
  return compile(expression, false);
}
</code></pre>
  <p data-lake-id="u2f3ca3cc" id="u2f3ca3cc"><br></p>
  <p data-lake-id="ub988ef7e" id="ub988ef7e"><br></p>
  <ul list="u08c46642">
   <li fid="u368220ec" data-lake-id="uddc1266e" id="uddc1266e"><span data-lake-id="u4f1065e8" id="u4f1065e8">可以看到，我们在使用表达式引擎时，默认是无缓存的模式进行编译的。</span></li>
   <li fid="u368220ec" data-lake-id="u297baeef" id="u297baeef"><span data-lake-id="ua077d9c6" id="ua077d9c6">AviatorEvaluatorInstance实例初始化时，会生成一个AviatorClassLoader类加载器</span></li>
  </ul>
  <p data-lake-id="u36f21c94" id="u36f21c94"><span data-lake-id="uca06a67e" id="uca06a67e">​</span><br></p>
  <pre lang="java"><code>
public final class AviatorEvaluatorInstance {

  private volatile AviatorClassLoader aviatorClassLoader = initAviatorClassLoader();

  private AviatorClassLoader initAviatorClassLoader() {
    return AccessController.doPrivileged(new PrivilegedAction&lt;AviatorClassLoader&gt;() {

      @Override
      public AviatorClassLoader run() {
        return new AviatorClassLoader(AviatorEvaluatorInstance.class.getClassLoader());
      }

    });
  }
  ...   
}
</code></pre>
  <p data-lake-id="u9684e16d" id="u9684e16d"><br></p>
  <ul list="u43a6291e">
   <li fid="u368220ec" data-lake-id="uaaf2d434" id="uaaf2d434"><span data-lake-id="u8010547b" id="u8010547b">编译过程主要分为如下几步</span></li>
  </ul>
  <ul list="u43a6291e" data-lake-indent="1">
   <li fid="u368220ec" data-lake-id="u7dac9b8f" id="u7dac9b8f"><span data-lake-id="ua6fb5722" id="ua6fb5722">文法分析</span></li>
   <li fid="u368220ec" data-lake-id="uaaa53f33" id="uaaa53f33"><span data-lake-id="u70a606ca" id="u70a606ca">初始化编码生成器</span></li>
   <li fid="u368220ec" data-lake-id="uab226e26" id="uab226e26"><span data-lake-id="ua60706e3" id="ua60706e3">语法解析器生成</span></li>
   <li fid="u368220ec" data-lake-id="u0aca9da0" id="u0aca9da0"><span data-lake-id="uc4b37ac3" id="uc4b37ac3">语法解析，实例化Class，最终的 Expression 对象</span></li>
  </ul>
  <p data-lake-id="u5d1f5383" id="u5d1f5383"><span data-lake-id="ua2c6f424" id="ua2c6f424">​</span><br></p>
  <pre lang="java"><code>
/**
  * 编译过程
**/
private Expression innerCompile(final String expression, final String sourceFile,
                                final boolean cached) {
    // 文法分析
    ExpressionLexer lexer = new ExpressionLexer(this, expression);
    // 初始化编码生成器
    CodeGenerator codeGenerator = newCodeGenerator(sourceFile, cached);
    // 语法解析器生成
    ExpressionParser parser = new ExpressionParser(this, lexer, codeGenerator);
    // 语法解析，实例化Class，最终的 Expression 对象
    Expression exp = parser.parse();
    if (getOptionValue(Options.TRACE_EVAL).bool) {
        ((BaseExpression) exp).setExpression(expression);
    }
    return exp;
}
</code></pre>
  <p data-lake-id="u4b3e5ce5" id="u4b3e5ce5"><br></p>
  <ul list="u0883a4df">
   <li fid="u0b5798ee" data-lake-id="u1e94b359" id="u1e94b359"><span data-lake-id="u266150f5" id="u266150f5">直接看编码生成器的初始化阶段</span></li>
  </ul>
  <ul list="u0883a4df" data-lake-indent="1">
   <li fid="u0b5798ee" data-lake-id="u11ec419c" id="u11ec419c"><span data-lake-id="u2ebcca8d" id="u2ebcca8d">首先，获取AviatorClassLoader类型的类加载器</span></li>
   <li fid="u0b5798ee" data-lake-id="ude49084e" id="ude49084e"><span data-lake-id="u024f2f3f" id="u024f2f3f">初始化OptimizeCodeGenerator的编码生成器</span></li>
  </ul>
  <ul list="u0883a4df" data-lake-indent="2">
   <li fid="u0b5798ee" data-lake-id="u71fc1e17" id="u71fc1e17"><span data-lake-id="u9170c992" id="u9170c992">类型为ASMCodeGenerator</span></li>
   <li fid="u0b5798ee" data-lake-id="u394b24f6" id="u394b24f6"><span data-lake-id="u63d135cc" id="u63d135cc">classLoader=AviatorClassLoader</span></li>
   <li fid="u0b5798ee" data-lake-id="uc2c9c973" id="uc2c9c973"><span data-lake-id="u69dfbeb7" id="u69dfbeb7">className="Script_" + System.currentTimeMillis() + "_" + CLASS_COUNTER.getAndIncrement(); </span><span data-lake-id="u783cf176" id="u783cf176" style="color: #13C2C2">- 与metaspace区的类信息吻合</span></li>
  </ul>
  <p data-lake-id="udf4ca338" id="udf4ca338"><span data-lake-id="u67db1a4f" id="u67db1a4f" style="color: #13C2C2">​</span><br></p>
  <pre lang="java"><code>
// 初始化编码生成器
public CodeGenerator newCodeGenerator(final String sourceFile, final boolean cached) {
    AviatorClassLoader classLoader = getAviatorClassLoader(cached);
    return newCodeGenerator(classLoader, sourceFile);

}

/**
   * Returns classloader
   *
   * @return
   */
public AviatorClassLoader getAviatorClassLoader(final boolean cached) {
    if (cached) {
        return this.aviatorClassLoader;
    } else {
        return new AviatorClassLoader(this.getClass().getClassLoader());
    }
}

/**
   * Returns CodeGenerator
   *
   * @return
   */
public CodeGenerator newCodeGenerator(final AviatorClassLoader classLoader,
                                      final String sourceFile) {
    switch (getOptimizeLevel()) {
        case AviatorEvaluator.COMPILE:
            ASMCodeGenerator asmCodeGenerator =
                new ASMCodeGenerator(this, sourceFile, classLoader, this.traceOutputStream);
            asmCodeGenerator.start();
            return asmCodeGenerator;
        case AviatorEvaluator.EVAL:
            // 默认走EVAL
            return new OptimizeCodeGenerator(this, sourceFile, classLoader, this.traceOutputStream);
        default:
            throw new IllegalArgumentException("Unknow option " + getOptimizeLevel());
    }
}

public OptimizeCodeGenerator(final AviatorEvaluatorInstance instance, final String sourceFile,
                             final ClassLoader classLoader, final OutputStream traceOutStream) {
    this.instance = instance;
    this.sourceFile = sourceFile;
    this.codeGen = new ASMCodeGenerator(instance, sourceFile, (AviatorClassLoader) classLoader,
                                        traceOutStream);
}

// 编码生成器，会创建一个匿名的类
public ASMCodeGenerator(final AviatorEvaluatorInstance instance, final String sourceFile,
      final AviatorClassLoader classLoader, final OutputStream traceOut) {
    this.classLoader = classLoader;
    this.instance = instance;
    this.compileEnv = new Env();
    this.sourceFile = sourceFile;
    this.compileEnv.setInstance(this.instance);
    // Generate inner class name
    this.className = "Script_" + System.currentTimeMillis() + "_" + CLASS_COUNTER.getAndIncrement();
    // Auto compute frames
    this.classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    // if (trace) {
    // this.traceClassVisitor = new TraceClassVisitor(this.clazzWriter, new PrintWriter(traceOut));
    // this.classWriter = new CheckClassAdapter(this.traceClassVisitor);
    // } else {
    // this.classWriter = new CheckClassAdapter(this.clazzWriter);
    // }
    visitClass();
  }
</code></pre>
  <p data-lake-id="uc8b41950" id="uc8b41950"><br></p>
  <ul list="u71a58c71">
   <li fid="u741535df" data-lake-id="uc4fed0de" id="uc4fed0de"><span data-lake-id="ub9e92768" id="ub9e92768">语法解析器生成</span></li>
  </ul>
  <ul list="u71a58c71" data-lake-indent="1">
   <li fid="u741535df" data-lake-id="u1d6f9248" id="u1d6f9248"><span data-lake-id="uc98da875" id="uc98da875">引用编码生成器</span></li>
   <li fid="u741535df" data-lake-id="uc7bbdf7c" id="uc7bbdf7c"><span data-lake-id="u0e258499" id="u0e258499">设置解析器，编码生成器引用this</span></li>
  </ul>
  <p data-lake-id="ucb2aa552" id="ucb2aa552"><span data-lake-id="uddde86ed" id="uddde86ed">​</span><br></p>
  <pre lang="java"><code>
  public ExpressionParser(final AviatorEvaluatorInstance instance, final ExpressionLexer lexer,
      final CodeGenerator codeGenerator) {
    super();
    this.scope = new ScopeInfo(0, 0, 0, 0, false, new ArrayDeque&lt;DepthState&gt;());
    this.instance = instance;
    this.captureFuncArgs = instance.getOptionValue(Options.CAPTURE_FUNCTION_ARGS).bool;
    this.lexer = lexer;
    this.lookhead = this.lexer.scan();
    if (this.lookhead != null) {
      this.parsedTokens++;
    }
    this.featureSet = this.instance.getOptionValue(Options.FEATURE_SET).featureSet;
    if (this.lookhead == null) {
      reportSyntaxError("blank script");
    }
    // 引用编码生成器
    setCodeGenerator(codeGenerator);
    // 设置解析器，编码生成器引用this
    getCodeGeneratorWithTimes().setParser(this);
  }
</code></pre>
  <p data-lake-id="u3d9f8651" id="u3d9f8651"><br></p>
  <ul list="u33c69aff">
   <li fid="u14a1d1e9" data-lake-id="u947eb4da" id="u947eb4da"><span data-lake-id="ub8b8d321" id="ub8b8d321">语法解析</span></li>
  </ul>
  <ul list="u33c69aff" data-lake-indent="1">
   <li fid="u14a1d1e9" data-lake-id="u1193c144" id="u1193c144"><span data-lake-id="u4facffc6" id="u4facffc6">实例化ClassExpression类型的对象后返回</span></li>
  </ul>
  <p data-lake-id="u0cd53997" id="u0cd53997"><span data-lake-id="ua53814e7" id="ua53814e7">​</span><br></p>
  <pre lang="java"><code>
  public Expression parse(final boolean reportErrorIfNotEOF) {
    StatementType statementType = statements();
    if (this.lookhead != null &amp;&amp; reportErrorIfNotEOF) {
      if (statementType == StatementType.Ternary) {
        reportSyntaxError("unexpect token '" + currentTokenLexeme()
            + "', maybe forget to insert ';' to complete last expression ");
      } else {
        reportSyntaxError("unexpect token '" + currentTokenLexeme() + "'");
      }
    }
    // 实例化
    return getCodeGeneratorWithTimes().getResult(true);
  }

  @Override
  public Expression getResult(final boolean unboxObject) {
    end(unboxObject);

    byte[] bytes = this.classWriter.toByteArray();
    try {
      Class&lt;?&gt; defineClass =
          ClassDefiner.defineClass(this.className, Expression.class, bytes, this.classLoader);
      Constructor&lt;?&gt; constructor =
          defineClass.getConstructor(AviatorEvaluatorInstance.class, List.class, SymbolTable.class);
      ClassExpression exp = (ClassExpression) constructor.newInstance(this.instance,
          new ArrayList&lt;String&gt;(this.varTokens.keySet()), this.symbolTable);
      exp.setLambdaBootstraps(this.lambdaBootstraps);
      exp.setFuncsArgs(this.funcsArgs);
      return exp;
    } catch (ExpressionRuntimeException e) {
      throw e;
    } catch (Throwable e) {
      if (e.getCause() instanceof ExpressionRuntimeException) {
        throw (ExpressionRuntimeException) e.getCause();
      }
      throw new CompileExpressionErrorException("define class error", e);
    }
  }
</code></pre>
  <p data-lake-id="u06a62f5c" id="u06a62f5c"><br></p>
  <p data-lake-id="u2fa18ccf" id="u2fa18ccf"><span data-lake-id="u5e8ba903" id="u5e8ba903">结论就是，</span><strong><span data-lake-id="u9ce87a8a" id="u9ce87a8a">无缓存情况下，每次编译表达式都会生成一个AviatorClassLoader类加载器+一个匿名的Express类型的class，metaspace的空间会逐步占满</span></strong></p>
  <p data-lake-id="u68d1c00a" id="u68d1c00a"><strong><span data-lake-id="u1ea2bb65" id="u1ea2bb65">​</span></strong><br></p>
  <p data-lake-id="uc06167a3" id="uc06167a3"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680091849585-85a8be75-fd21-49ff-ba2b-02fde1a07d1f.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_21%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u98cee774" id="u98cee774"><br></p>
  <h3 data-lake-id="GvTGt" id="GvTGt"><span data-lake-id="uaf5565b2" id="uaf5565b2">问题解决</span></h3>
  <p data-lake-id="u74283d02" id="u74283d02"><span data-lake-id="u85ca933e" id="u85ca933e">解决思路就是官方支持使用缓存的方式。在github上也有人提到过类似的问题。</span></p>
  <p data-lake-id="ubb58109d" id="ubb58109d"><br></p>
  <p data-lake-id="ud4a81aa5" id="ud4a81aa5"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680091876431-e2a4c631-7d40-4b63-8432-fb7f19656e8d.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_21%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u0bc0bb4a" id="u0bc0bb4a"><br></p>
  <p data-lake-id="u8c30e68a" id="u8c30e68a"><br></p>
  <ul list="u20a1c9be">
   <li fid="uaf017a19" data-lake-id="ud5135f8b" id="ud5135f8b"><span data-lake-id="udfc0a550" id="udfc0a550">使用cacheKey的缓存方案</span></li>
  </ul>
  <ul list="u20a1c9be" data-lake-indent="1">
   <li fid="uaf017a19" data-lake-id="u29ecf3f8" id="u29ecf3f8"><span data-lake-id="ub9f0ba30" id="ub9f0ba30">public Expression </span><span data-lake-id="ub707eb82" id="ub707eb82" style="color: #ffc66d">compile</span><span data-lake-id="u530c2323" id="u530c2323">(</span><span data-lake-id="u659f422f" id="u659f422f" style="color: #cc7832">final </span><span data-lake-id="u22d63cf5" id="u22d63cf5">String cacheKey</span><span data-lake-id="uadc24074" id="uadc24074" style="color: #cc7832">, final </span><span data-lake-id="u15548db2" id="u15548db2">String expression</span><span data-lake-id="ub5f99d9a" id="ub5f99d9a" style="color: #cc7832">, final boolean </span><span data-lake-id="uba635517" id="uba635517">cached)</span></li>
  </ul>
  <p data-lake-id="uad2c26a6" id="uad2c26a6"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680091893999-0e2ded1d-289c-4d31-a86d-e8157a5d7948.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_44%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <ul list="u20a1c9be" start="2">
   <li fid="uaf017a19" data-lake-id="u8654ae04" id="u8654ae04"><span data-lake-id="u64a952da" id="u64a952da">key组装规则</span></li>
  </ul>
  <ul list="u20a1c9be" data-lake-indent="1">
   <li fid="uaf017a19" data-lake-id="ucf98a512" id="ucf98a512"><span data-lake-id="u31f94008" id="u31f94008">${product}_${priceBaseDTO.code}_${simpleName}_${method}</span></li>
  </ul>
  <p data-lake-id="ue03c2177" id="ue03c2177" style="text-align: center"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1680091893680-d2c76887-5bae-44e7-bfb2-3421adf1fade.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_27%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <h2 data-lake-id="XZ0pf" id="XZ0pf"><span data-lake-id="u9ca55963" id="u9ca55963">​</span><br></h2>
 </body>
</html>